﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;

namespace EFSPWebParts
{
    public partial class ListViewNoHeaderUserControl : UserControl
    {
        #region properties and logging
        public string WebUrl { get; set; }
        public string ListViewUrl { get; set; }
        public bool ShowHeader { get; set; }
        public bool CheckPermission { get; set; }

        private void MyTraceToDeveloper(string strMessage)
        {
            //showMessage(strMessage);
        }

        private void showMessage(string strMessage)
        {
            Label1.Text += strMessage + @"<br />";
            Label1.Visible = true;
        }
        #endregion

        private bool checkViewRightOverList()
        {
            bool boolReturn = false;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite objSPSite = new SPSite(SPContext.Current.Site.ID))
                {
                    //using (SPWeb objSPWeb = objSPSite.OpenWeb(SPContext.Current.Web.ID))
                    using (SPWeb objSPWeb = objSPSite.OpenWeb(WebUrl))
                    {
                        try
                        {
                            SPView objSPView = objSPWeb.GetViewFromUrl(ListViewUrl);
                            SPList objSPList = objSPView.ParentList;
                            if (objSPList.DoesUserHavePermissions(SPContext.Current.Web.CurrentUser, SPBasePermissions.ViewListItems))
                            {
                                boolReturn = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new System.IO.InvalidDataException(@"Invalid list structure", ex);
                        }
                    }
                }
            });

            return boolReturn;
        }

        private bool GetHttpStatus(string strUrl)
        {
            HttpWebRequest request = null;
            bool returnStatus = false;

            try
            {
                if (strUrl != null && strUrl != string.Empty)
                {
                    Uri uri = new Uri(strUrl);
                    request = (HttpWebRequest)HttpWebRequest.Create(uri);
                    request.Method = "GET";
                    request.KeepAlive = true;
                    request.Accept = @"*/*";
                    request.AllowAutoRedirect = true;
                    //request.Credentials = CredentialCache.DefaultCredentials;
                    request.UseDefaultCredentials = true;
                    request.PreAuthenticate = true;
                    request.Credentials = CredentialCache.DefaultCredentials;

                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        returnStatus = true;
                    }
                }
            }
            //401 status codes with throw an exception in this code
            catch (System.Net.WebException ex)
            {
                returnStatus = false;
            }
            catch (System.Exception ex)
            {
                returnStatus = false;
            }

            return returnStatus;
        }

        private List<int> GetListItemIDs(SPView objSPView)
        {
            Guid guidFieldNameUrl = Guid.Empty;
            SPFieldUrlValue valueUrl = null;
            string strURL = string.Empty;
            List<int> listItemID = new List<int>();

            SPList objSPList = objSPView.ParentList;
            SPListItemCollection objSPListItemCollection = objSPList.GetItems(objSPView);
            foreach (SPField objSPField in objSPListItemCollection.Fields)
            {
                if (objSPField.Type == SPFieldType.URL || objSPField.Type == SPFieldType.Computed)
                {
                    if (objSPList.Fields[objSPField.Title].FieldValueType != null && objSPList.Fields[objSPField.Title].FieldValueType.Name.Equals("SPFieldUrlValue", StringComparison.InvariantCultureIgnoreCase))
                    {
                        guidFieldNameUrl = objSPField.Id;
                        break;
                    }
                }
            }

            if (guidFieldNameUrl != Guid.Empty)
            {
                foreach (SPListItem item in objSPListItemCollection)
                {
                    valueUrl = new SPFieldUrlValue(item[guidFieldNameUrl].ToString());
                    strURL = valueUrl.Url;
                    if (GetHttpStatus(strURL) == false)
                    {
                        MyTraceToDeveloper(string.Format("Cannot access url: {0}", strURL));
                        listItemID.Add(item.ID);
                    }
                    else
                    {
                        MyTraceToDeveloper(string.Format("Can access url: {0}", strURL));
                    }
                }
            }

            return listItemID;
        }

        private string GetNewQueryBasedOnAccessPermissions(SPView objSPView)
        {
            string strPermissionQuery = string.Empty;
            string strCurrentWhere = string.Empty;
            List<int> listItemIDs = null;

            listItemIDs = GetListItemIDs(objSPView);
            if (listItemIDs.Count > 0)
            {
                foreach (int iItemID in listItemIDs)
                {
                    strCurrentWhere = string.Format(@"<Neq><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Neq>", iItemID);
                    if (string.IsNullOrEmpty(strPermissionQuery))
                    {
                        strPermissionQuery = strCurrentWhere;
                    }
                    else
                    {
                        strPermissionQuery = string.Format(@"<And>{0}{1}</And>", strPermissionQuery, strCurrentWhere);
                    }
                }
            }


            return strPermissionQuery;
        }

        //private string GetNewQueryBasedOnAccessPermissions(SPView objSPView)
        //{
        //    string strPermissionQuery = string.Empty;
        //    Guid guidFieldNameUrl = Guid.Empty;
        //    SPFieldUrlValue valueUrl = null;
        //    string strURL = string.Empty;
        //    List<int> listItemID = new List<int>();

        //    SPList objSPList = objSPView.ParentList;
        //    SPListItemCollection objSPListItemCollection = objSPList.GetItems(objSPView);
        //    foreach (SPField objSPField in objSPListItemCollection.Fields)
        //    {
        //        if (objSPField.Type == SPFieldType.URL)
        //        {
        //            //strFieldNameUrl = objSPField.InternalName;
        //            guidFieldNameUrl = objSPField.Id;
        //        }
        //    }

        //    if (guidFieldNameUrl != Guid.Empty)
        //    {
        //        foreach (SPListItem item in objSPListItemCollection)
        //        {
        //            valueUrl = new SPFieldUrlValue(item[guidFieldNameUrl].ToString());
        //            strURL = valueUrl.Url;
        //            listItemID.Add(item.ID);
        //        }
        //    }

        //    return strPermissionQuery;
        //}

        private string GetFinalQuery(string strOriginalQuery, string strPermissionQuery)
        {
            string strFinalQuery = string.Empty;
            string strOriginalWhere = string.Empty;
            string strOriginalOrder = string.Empty;
            int iPosStart = int.MinValue;
            int iPosEnd = int.MinValue;

            iPosStart = strOriginalQuery.IndexOf(@"<OrderBy>");
            iPosEnd = strOriginalQuery.IndexOf(@"</OrderBy>");
            if (iPosStart >= 0)
            {
                strOriginalOrder = strOriginalQuery.Substring(iPosStart, iPosEnd - iPosStart + 10);
            }

            if (string.IsNullOrEmpty(strPermissionQuery) == false)
            {
                if (string.IsNullOrEmpty(strOriginalQuery))
                {
                    strFinalQuery = string.Format(@"<Where>{0}</Where>", strPermissionQuery);
                }
                else if (strOriginalQuery.Contains(@"<Where>"))
                {
                    iPosStart = strOriginalQuery.IndexOf(@"<Where>");
                    iPosEnd = strOriginalQuery.IndexOf(@"</Where>");
                    strOriginalWhere = strOriginalQuery.Substring(iPosStart + 7, iPosEnd - iPosStart - 7);

                    strFinalQuery = string.Format(@"<Where><And>{0}{1}</And></Where>{2}", strOriginalWhere, strPermissionQuery, strOriginalOrder);
                }
                else
                {
                    strFinalQuery = string.Format(@"<Where>{0}</Where>{1}", strPermissionQuery, strOriginalQuery);
                }
            }
            else
            {
                strFinalQuery = strOriginalQuery;
            }

            return strFinalQuery;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            string strHtml = string.Empty;
            string strOriginalQuery = string.Empty;
            string strPermissionQuery = string.Empty;
            string strFinalQuery = string.Empty;

            //Label1.Text = DateTime.Now.ToString();

            try
            {
                //SPSecurity.RunWithElevatedPrivileges(delegate()
                //{
                using (SPSite objSPSite = new SPSite(SPContext.Current.Site.ID))
                {
                    //using (SPWeb objSPWeb = objSPSite.OpenWeb(SPContext.Current.Web.ID))
                    using (SPWeb objSPWeb = objSPSite.OpenWeb(WebUrl))
                    {
                        if (string.IsNullOrEmpty(ListViewUrl))
                        {
                            //ListViewUrl = @"/SitePages/Forms/AllPages.aspx";
                            showMessage(string.Format(@"Please specify valid site relative list view URL. Current value is ({0})", ListViewUrl));
                            return;
                        }
                        if (ListViewUrl.StartsWith(@"/"))
                        {
                            ListViewUrl = ListViewUrl.Substring(1);
                        }
                        if (false == checkViewRightOverList())
                        {
                            showMessage(string.Format(@"Web: {0}<br />No view rights over list view ({1})", WebUrl, ListViewUrl));
                            return;
                        }

                        SPView objSPView = objSPWeb.GetViewFromUrl(ListViewUrl);
                        if (objSPView == null)
                        {
                            showMessage(string.Format(@"Please specify valid site relative list view URL. Current value is ({0})", ListViewUrl));
                            return;
                        }
                        else
                        {
                            if (CheckPermission)
                            {
                                strOriginalQuery = objSPView.Query;
                                strPermissionQuery = GetNewQueryBasedOnAccessPermissions(objSPView);
                                strFinalQuery = GetFinalQuery(strOriginalQuery, strPermissionQuery);
                                objSPView.Query = strFinalQuery;
                            }

                            strHtml = objSPView.RenderAsHtml(false, false, ListViewUrl);

                            if (ShowHeader == false)
                            {
                                strHtml = strHtml.Replace(@"class=""ms-viewheadertr""", @"class=""ms-viewheadertr"" style=""display: none""");
                            }

                            Label1.Text = strHtml;

                            //LabelStatus.Text = Microsoft.SharePoint.Utilities.SPEncode.HtmlEncode(strHtml);
                            //LabelStatus.Visible = true;
                        }
                    }
                }
                //});
            }
            catch (Exception ex)
            {
                showMessage(string.Format(@"WebUrl={0}<br />ListViewUrl={1}<br />ShowHeader={2}<br />ex.Message={3}<br />ex.StackTrace={4}<br />The list view may not exist in the specified sub site.",
                    WebUrl, ListViewUrl, ShowHeader, ex.Message, ex.StackTrace));
                return;
            }
        }
    }
}
